package com.insta.formation.calendar.model;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;


/**
 * This class allows to create new events and get a list of events.
 * 
 * @author julien
 * 
 */
@Entity
@Table(name = "CALENDAR")
public class Calendar
{
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private int id;

	@Column(nullable = false)
	private String name;

	@ManyToOne
	@JoinColumn(name = "Owner_FK", nullable = false)
	private Person owner;

	@OneToMany(mappedBy = "calendar", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
	private Set<Event> events;
	
	@ManyToMany(targetEntity = com.insta.formation.calendar.model.Person.class, cascade = { CascadeType.PERSIST, CascadeType.MERGE })
	@JoinTable(name = "CALENDAR_PERSON", joinColumns = @JoinColumn(name = "CALENDAR_ID"), inverseJoinColumns = @JoinColumn(name = "PERSON_ID"))
	private Set<Person> guests;
	

	public Calendar() {
		events = new HashSet<Event>();
	}

	/**
	 * Gets the identifier of the calendar.
	 * 
	 * @return - identifier of the calendar.
	 */
	public int getId()
	{
		return id;
	}

	/**
	 * Sets the identifier of the calendar.
	 * 
	 * @param id
	 *            - identifier of the calendar.
	 */
	public void setId(int id)
	{
		this.id = id;
	}

	/**
	 * Gets the name of the calendar.
	 * 
	 * @return - name of the calendar.
	 */
	public String getName()
	{
		return name;
	}

	/**
	 * Sets the name of the calendar.
	 * 
	 * @param name
	 *            - name of the calendar.
	 */
	public void setName(String name)
	{
		this.name = name;
	}

	/**
	 * Gets the owner of the calendar
	 * 
	 * @return - owner of the calendar
	 */
	public Person getOwner()
	{
		return owner;
	}

	/**
	 * Sets the owner of the calendar
	 * 
	 * @param owner
	 *            - owner of the calendar
	 */
	public void setOwner(Person owner)
	{
		this.owner = owner;
	}

	/**
	 * Gets all events in Calendar
	 * 
	 * @return - all events in Calendar
	 */
	public Set<Event> getEvents()
	{
		return this.events;
	}

	/**
	 * Sets all events in Calendar
	 * 
	 * @param - all events in Calendar
	 */
	public void setEvents(Set<Event> events)
	{
		this.events = events;
	}

	/**
	 * Create a new Event of the calendar
	 * 
	 * @param event
	 *            - new Event of the calendar
	 */
	public void addEvent(Event event)
	{
		event.setCalendar(this);
		this.events.add(event);
	}
	
	public Event getEvent(String eventName)
	{
		Event eventTmp = null;
		for (Event event : getEvents()) {
			if (event.getName().equals(eventName)) {
				eventTmp = event;
				break;
			}
		}
		return eventTmp;
	}

	@Override
	public int hashCode()
	{
		final int prime = 31;
		int result = 1;
		result = prime * result + ((this.name == null) ? 0 : this.name.hashCode());
		result = prime * result + ((this.owner == null) ? 0 : this.owner.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj)
	{
		if (this == obj) return true;
		if (obj == null) return false;
		if (getClass() != obj.getClass()) return false;
		Calendar other = (Calendar) obj;
		if (this.name == null) {
			if (other.name != null) return false;
		}
		else if (!this.name.equals(other.name)) return false;
		if (this.owner == null) {
			if (other.owner != null) return false;
		}
		else if (!this.owner.equals(other.owner)) return false;
		return true;
	}

	@Override
	public String toString()
	{
		return "Calendar [id=" + this.id + ", name=" + this.name + ", owner=" + this.owner + ", events=" + this.events + "]";
	}

}
